#pragma once
// -------------------------------------------------
// ZED Kit
// -------------------------------------------------
//   File Name: file_selector.hpp
//      Author: Ziming Li
//     Created: 2022-09-17
// -------------------------------------------------
// Copyright (C) 2022 MingYang Software Technology.
// -------------------------------------------------

#ifndef ZED_GUI_FILE_SELECTOR_HPP
#define ZED_GUI_FILE_SELECTOR_HPP

#include "../file/path.hpp"

namespace zed {

class file_selector
{
public:
    static file_selector for_opening(void) { return file_selector(type_t::open); }
    static file_selector for_saving(void) { return file_selector(type_t::save); }

    path::string_t run(void);

#if defined(_Z_OS_WINDOWS)
    OPENFILENAMEW m_ofn;
#else
#   error TODO:
#endif
private:
    enum class type_t { open, save };
    file_selector(type_t type);

    void initialize(void);

    const type_t m_type;
#ifdef _Z_OS_WINDOWS
    WCHAR m_file_name[MAX_PATH];
#endif
};

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Implementations

inline file_selector::file_selector(type_t type) : m_type(type)
{
    initialize();
}

#ifdef _Z_OS_WINDOWS
inline void file_selector::initialize(void)
{
    memset(&m_ofn, 0, sizeof(m_ofn));
    m_ofn.lStructSize = sizeof(m_ofn);

    memset(m_file_name, 0, sizeof(m_file_name));
    m_ofn.lpstrFile = m_file_name;
    m_ofn.nMaxFile = std::size(m_file_name);

    m_ofn.Flags = OFN_EXPLORER | OFN_ENABLESIZING | OFN_PATHMUSTEXIST;
    switch (m_type)
    {
        case type_t::open:
            m_ofn.Flags |= OFN_FILEMUSTEXIST;
            break;
        case type_t::save:
            m_ofn.Flags |= OFN_OVERWRITEPROMPT;
            break;
    }
}

inline path::string_t file_selector::run(void)
{
    path::string_t ret;

    BOOL b = FALSE;
    switch (m_type)
    {
        case type_t::open:
            b = ::GetOpenFileNameW(&m_ofn);
            break;
        case type_t::save:
            b = ::GetSaveFileNameW(&m_ofn);
            break;
    }

    if (b)
        ret.assign(m_ofn.lpstrFile);
    return ret;
}
#endif

} // namespace zed

#endif // ZED_GUI_FILE_SELECTOR_HPP
